package jm.easyconfig;

import java.util.Date;
import java.util.concurrent.TimeUnit;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.ClassUtils;

public class RedisCacheHelper {
	boolean inited;
	boolean redisAvailble;
	String redisKey;

	ValueOperations<String, Long> valOp;

	@SuppressWarnings({ "rawtypes", "unchecked" })
	boolean init() {
		if (inited)
			return true;

		redisAvailble = false;

		if (ClassUtils.isPresent("org.springframework.data.redis.core.RedisTemplate",
				this.getClass().getClassLoader())) {

			String[] names = CfgContextEnvironmentAware.applicationContext.getBeanNamesForType(RedisTemplate.class,
					false, false);

			redisAvailble = names.length > 0;

			for (String name : names) {
				try {

					RedisTemplate redisTemplate = (RedisTemplate) CfgContextEnvironmentAware.applicationContext
							.getBean(name);// "redisTemplate"

					redisKey = CfgContextEnvironmentAware.clientUniqueName(CfgContextEnvironmentAware.environment);

					if (redisKey == null || "".equals(redisKey)) {
						redisKey = new Date().toString();
					}

					redisKey = "easyconfig.sourceLastTime:" + redisKey;

					valOp = redisTemplate.opsForValue();
					Long val = valOp.get(redisKey);
					if (val == null) {
						val = Long.MAX_VALUE;
						valOp.set(redisKey, val, 1, TimeUnit.DAYS);
					}

					break;

				} catch (Throwable e) {
					redisAvailble = false;
				}
			}
		}

		inited = true;

		CfgHelper.logger.info("redis for cache is {} available", redisAvailble ? "" : "not");

		return true;
	}

	boolean sameWith(long localTime) {
		try {
			long remote = valOp.get(redisKey);
			return remote == localTime;
		} catch (Throwable e) {
			CfgHelper.logger.error("wrong when reading value from redis.\n message:{}", e.getMessage());
			return false;
		}
	}

	void setSourceTimestamp(long val) {
		try {
			valOp.set(redisKey, val, 1, TimeUnit.DAYS);
		} catch (Throwable e) {
			CfgHelper.logger.error("wrong when updating value in redis.\n message:{}", e.getMessage());
		}
	}

	boolean isAvailable() {
		return init() && redisAvailble;
	}
}
